%{
package parser



%}

// Token类型定义
%union {
	node     Node
	stmt     Statement
	expr     Expression
	tableRef *TableRef
	orderBy  *OrderByExpr
	updateExpr *UpdateExpr
	whenClause *WhenClause
	windowSpec *WindowSpec
	windowFrame *WindowFrame
	frameBound *FrameBound
	joinExpr *JoinExpr
	
	stmtList       []Statement
	exprList       []Expression
	tableList      []TableRef
	orderList      []OrderByExpr
	updateList     []UpdateExpr
	whenList       []*WhenClause
	joinList       []JoinExpr
	columnList     []string
	columnDef      *ColumnDef
	columnDefList  []*ColumnDef
	typeName       *TypeName
	valuesList     [][]Expression
	
	str      string
	intVal   int64
	floatVal float64
	boolVal  bool
	binaryOp BinaryOp
	unaryOp  UnaryOp
	joinType JoinType
	orderDir OrderDirection
	nullsOrder NullsOrder
	literalType LiteralType
}

// Token声明
%token <str> TOK_IDENT TOK_STRING
%token <intVal> TOK_INTEGER
%token <floatVal> TOK_FLOAT

// 操作符
%token TOK_EQ TOK_NE TOK_LT TOK_LE TOK_GT TOK_GE
%token TOK_PLUS TOK_MINUS TOK_MULTIPLY TOK_DIVIDE TOK_MODULO TOK_CONCAT
%token TOK_LSHIFT TOK_RSHIFT TOK_REGEX TOK_IREGEX TOK_NOT_REGEX TOK_NOT_IREGEX

// 分隔符
%token TOK_COMMA TOK_SEMICOLON TOK_LPAREN TOK_RPAREN TOK_DOT

// 关键字
%token TOK_SELECT TOK_FROM TOK_WHERE TOK_INSERT TOK_INTO TOK_VALUES
%token TOK_UPDATE TOK_SET TOK_DELETE TOK_JOIN TOK_INNER TOK_LEFT TOK_RIGHT
%token TOK_FULL TOK_CROSS TOK_ON TOK_AS TOK_AND TOK_OR TOK_NOT TOK_IN
%token TOK_LIKE TOK_ILIKE TOK_BETWEEN TOK_IS TOK_NULL TOK_TRUE TOK_FALSE
%token TOK_DISTINCT TOK_ALL TOK_ANY TOK_SOME TOK_EXISTS TOK_CASE TOK_WHEN
%token TOK_THEN TOK_ELSE TOK_END TOK_GROUP TOK_BY TOK_HAVING TOK_ORDER
%token TOK_ASC TOK_DESC TOK_LIMIT TOK_OFFSET TOK_UNION TOK_INTERSECT
%token TOK_EXCEPT TOK_WITH TOK_OVER TOK_PARTITION TOK_ROWS TOK_RANGE
%token TOK_UNBOUNDED TOK_PRECEDING TOK_FOLLOWING TOK_CURRENT TOK_ROW
%token TOK_FIRST TOK_LAST TOK_NULLS TOK_CREATE TOK_TABLE TOK_PRIMARY
%token TOK_KEY TOK_UNIQUE TOK_FOREIGN TOK_REFERENCES TOK_CHECK
%token TOK_DEFAULT TOK_CONSTRAINT TOK_VARCHAR TOK_DECIMAL
%token TOK_BOOLEAN TOK_TEXT TOK_TIMESTAMP TOK_DATE TOK_TIME

// 类型声明
%type <stmt> statement select_stmt insert_stmt update_stmt delete_stmt create_table_stmt
%type <expr> expression primary_expr binary_expr unary_expr function_call
%type <expr> literal column_ref subquery_expr case_expr
%type <columnDefList> column_def_list
%type <columnDef> column_def
%type <typeName> data_type
%type <tableRef> table_ref
%type <orderBy> order_by_item
%type <updateExpr> update_item
%type <whenClause> when_clause
%type <windowSpec> window_spec
%type <windowFrame> window_frame
%type <frameBound> frame_extent frame_bound
%type <joinExpr> join_clause

%type <exprList> expression_list target_list where_clause having_clause
%type <exprList> group_by_clause limit_clause offset_clause
%type <orderList> order_by_clause
%type <tableList> from_clause table_ref_list
%type <orderList> order_by_list
%type <updateList> update_list
%type <whenList> when_clause_list
%type <joinList> join_clause_list
%type <columnList> insert_column_list
%type <valuesList> values_list

%type <binaryOp> comparison_op arithmetic_op logical_op
%type <unaryOp> unary_op
%type <joinType> join_type
%type <orderDir> order_direction
%type <nullsOrder> nulls_order

// 操作符优先级
%left TOK_OR
%left TOK_AND
%left TOK_EQ TOK_NE TOK_LT TOK_LE TOK_GT TOK_GE TOK_LIKE TOK_ILIKE TOK_IN TOK_EXISTS
%right TOK_NOT
%left TOK_PLUS TOK_MINUS TOK_CONCAT
%left TOK_MULTIPLY TOK_DIVIDE TOK_MODULO
%right UMINUS UPLUS
%left TOK_DOT

%%

// 开始规则
start:
	statement
	{
		yylex.(*Lexer).result = $1
	}

// 语句规则
statement:
	select_stmt { $$ = $1 }
|	select_stmt TOK_SEMICOLON { $$ = $1 }
|	insert_stmt { $$ = $1 }
|	insert_stmt TOK_SEMICOLON { $$ = $1 }
|	update_stmt { $$ = $1 }
|	update_stmt TOK_SEMICOLON { $$ = $1 }
|	delete_stmt { $$ = $1 }
|	delete_stmt TOK_SEMICOLON { $$ = $1 }
|	create_table_stmt { $$ = $1 }
|	create_table_stmt TOK_SEMICOLON { $$ = $1 }

// SELECT语句
select_stmt:
	TOK_SELECT target_list from_clause where_clause group_by_clause having_clause order_by_clause limit_clause offset_clause
	{
		$$ = &SelectStmt{
			Targets: $2,
			From: $3,
			Where: getFirstExpr($4),
			GroupBy: $5,
			Having: getFirstExpr($6),
			OrderBy: $7,
			Limit: getFirstExpr($8),
			Offset: getFirstExpr($9),
		}
	}
|	TOK_SELECT TOK_DISTINCT target_list from_clause where_clause group_by_clause having_clause order_by_clause limit_clause offset_clause
	{
		$$ = &SelectStmt{
			Targets: $3,
			From: $4,
			Where: getFirstExpr($5),
			GroupBy: $6,
			Having: getFirstExpr($7),
			OrderBy: $8,
			Limit: getFirstExpr($9),
			Offset: getFirstExpr($10),
			Distinct: true,
		}
	}
|	TOK_SELECT error
	{
		// 错误恢复：SELECT语句语法错误
		$$ = nil
	}

// INSERT语句
insert_stmt:
	TOK_INSERT TOK_INTO table_ref TOK_LPAREN insert_column_list TOK_RPAREN TOK_VALUES values_list
	{
		$$ = &InsertStmt{
			Table: $3,
			Columns: $5,
			Values: $8,
		}
	}
|	TOK_INSERT TOK_INTO table_ref TOK_VALUES values_list
	{
		$$ = &InsertStmt{
			Table: $3,
			Values: $5,
		}
	}
|	TOK_INSERT TOK_INTO table_ref TOK_LPAREN insert_column_list TOK_RPAREN select_stmt
	{
		$$ = &InsertStmt{
			Table: $3,
			Columns: $5,
			Select: $7.(*SelectStmt),
		}
	}
|	TOK_INSERT error
	{
		// 错误恢复：INSERT语句语法错误
		$$ = nil
	}

// UPDATE语句
update_stmt:
	TOK_UPDATE table_ref TOK_SET update_list where_clause
	{
		$$ = &UpdateStmt{
			Table: $2,
			Set: $4,
			Where: getFirstExpr($5),
		}
	}
|	TOK_UPDATE error
	{
		// 错误恢复：UPDATE语句语法错误
		$$ = nil
	}

// DELETE语句
delete_stmt:
	TOK_DELETE TOK_FROM table_ref where_clause
	{
		$$ = &DeleteStmt{
			Table: $3,
			Where: getFirstExpr($4),
		}
	}
|	TOK_DELETE error
	{
		// 错误恢复：DELETE语句语法错误
		$$ = nil
	}

// CREATE TABLE语句
create_table_stmt:
	TOK_CREATE TOK_TABLE TOK_IDENT TOK_LPAREN column_def_list TOK_RPAREN
	{
		$$ = &CreateTableStmt{
			Table: &TableRef{Name: $3},
			Columns: $5,
		}
	}

// 目标列表
target_list:
	expression
	{
		$$ = []Expression{$1}
	}
|	TOK_MULTIPLY
	{
		$$ = []Expression{&ColumnRef{Column: "*"}}
	}
|	target_list TOK_COMMA expression
	{
		$$ = append($1, $3)
	}

// FROM子句
from_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_FROM table_ref_list
	{
		$$ = $2
	}

// 表引用列表
table_ref_list:
	table_ref
	{
		$$ = []TableRef{*$1}
	}
|	table_ref_list TOK_COMMA table_ref
	{
		$$ = append($1, *$3)
	}

// 表引用
table_ref:
	TOK_IDENT
	{
		$$ = &TableRef{Name: $1}
	}
|	TOK_IDENT TOK_AS TOK_IDENT
	{
		$$ = &TableRef{Name: $1, Alias: $3}
	}
|	TOK_IDENT TOK_IDENT
	{
		$$ = &TableRef{Name: $1, Alias: $2}
	}
|	table_ref join_clause_list
	{
		$1.Joins = $2
		$$ = $1
	}

// JOIN子句列表
join_clause_list:
	join_clause
	{
		$$ = []JoinExpr{*$1}
	}
|	join_clause_list join_clause
	{
		$$ = append($1, *$2)
	}

// JOIN子句
join_clause:
	join_type TOK_JOIN table_ref TOK_ON expression
	{
		$$ = &JoinExpr{
			Type: $1,
			Table: $3,
			Condition: $5,
		}
	}
|	TOK_JOIN table_ref TOK_ON expression
	{
		$$ = &JoinExpr{
			Type: InnerJoin,
			Table: $2,
			Condition: $4,
		}
	}

// JOIN类型
join_type:
	TOK_INNER { $$ = InnerJoin }
|	TOK_LEFT { $$ = LeftJoin }
|	TOK_RIGHT { $$ = RightJoin }
|	TOK_FULL { $$ = FullJoin }
|	TOK_CROSS { $$ = CrossJoin }

// WHERE子句
where_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_WHERE expression
	{
		$$ = []Expression{$2}
	}

// GROUP BY子句
group_by_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_GROUP TOK_BY expression_list
	{
		$$ = $3
	}

// HAVING子句
having_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_HAVING expression
	{
		$$ = []Expression{$2}
	}

// ORDER BY子句
order_by_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_ORDER TOK_BY order_by_list
	{
		$$ = $3
	}

// ORDER BY列表
order_by_list:
	order_by_item
	{
		$$ = []OrderByExpr{*$1}
	}
|	order_by_list TOK_COMMA order_by_item
	{
		$$ = append($1, *$3)
	}

// ORDER BY项
order_by_item:
	expression
	{
		$$ = &OrderByExpr{Expr: $1, Direction: ASC}
	}
|	expression order_direction
	{
		$$ = &OrderByExpr{Expr: $1, Direction: $2}
	}
|	expression order_direction nulls_order
	{
		$$ = &OrderByExpr{Expr: $1, Direction: $2, Nulls: $3}
	}

// 排序方向
order_direction:
	TOK_ASC { $$ = ASC }
|	TOK_DESC { $$ = DESC }

// NULLS排序
nulls_order:
	TOK_NULLS TOK_FIRST { $$ = NullsFirst }
|	TOK_NULLS TOK_LAST { $$ = NullsLast }

// LIMIT子句
limit_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_LIMIT expression
	{
		$$ = []Expression{$2}
	}

// OFFSET子句
offset_clause:
	/* empty */
	{
		$$ = nil
	}
|	TOK_OFFSET expression
	{
		$$ = []Expression{$2}
	}

// 表达式列表
expression_list:
	expression
	{
		$$ = []Expression{$1}
	}
|	expression_list TOK_COMMA expression
	{
		$$ = append($1, $3)
	}

// 表达式
expression:
	primary_expr { $$ = $1 }
|	binary_expr { $$ = $1 }
|	unary_expr { $$ = $1 }
|	function_call { $$ = $1 }
|	subquery_expr { $$ = $1 }
|	case_expr { $$ = $1 }
|	TOK_EXISTS TOK_LPAREN subquery_expr TOK_RPAREN
	{
		$$ = &ExistsExpr{Subquery: $3.(*SubqueryExpr)}
	}

// 主表达式
primary_expr:
	literal { $$ = $1 }
|	column_ref { $$ = $1 }
|	TOK_LPAREN expression TOK_RPAREN { $$ = $2 }

// 二元表达式
binary_expr:
	expression comparison_op expression
	{
		$$ = &BinaryExpr{Left: $1, Operator: $2, Right: $3}
	}
|	expression arithmetic_op expression
	{
		$$ = &BinaryExpr{Left: $1, Operator: $2, Right: $3}
	}
|	expression logical_op expression
	{
		$$ = &BinaryExpr{Left: $1, Operator: $2, Right: $3}
	}
|	expression TOK_LIKE expression
	{
		$$ = &BinaryExpr{Left: $1, Operator: LIKE, Right: $3}
	}
|	expression TOK_ILIKE expression
	{
		$$ = &BinaryExpr{Left: $1, Operator: ILIKE, Right: $3}
	}
|	expression TOK_IS TOK_NULL
	{
		$$ = &BinaryExpr{Left: $1, Operator: IS_NULL, Right: &Literal{Value: nil, Type: NullLiteral}}
	}
|	expression TOK_IS TOK_NOT TOK_NULL
	{
		$$ = &BinaryExpr{Left: $1, Operator: IS_NOT_NULL, Right: &Literal{Value: nil, Type: NullLiteral}}
	}
|	expression TOK_IN TOK_LPAREN expression_list TOK_RPAREN
	{
		$$ = &InExpr{Expr: $1, List: $4}
	}
|	expression TOK_IN TOK_LPAREN subquery_expr TOK_RPAREN
	{
		$$ = &InExpr{Expr: $1, Subquery: $4.(*SubqueryExpr)}
	}
|	expression TOK_NOT TOK_IN TOK_LPAREN expression_list TOK_RPAREN
	{
		$$ = &InExpr{Expr: $1, List: $5, Not: true}
	}
|	expression TOK_NOT TOK_IN TOK_LPAREN subquery_expr TOK_RPAREN
	{
		$$ = &InExpr{Expr: $1, Subquery: $5.(*SubqueryExpr), Not: true}
	}


// 一元表达式
unary_expr:
	unary_op expression %prec UMINUS
	{
		$$ = &UnaryExpr{Operator: $1, Operand: $2}
	}

// 函数调用
function_call:
	TOK_IDENT TOK_LPAREN TOK_RPAREN
	{
		$$ = &FunctionCall{Name: $1, Args: nil}
	}
|	TOK_IDENT TOK_LPAREN TOK_MULTIPLY TOK_RPAREN
	{
		$$ = &FunctionCall{Name: $1, Args: []Expression{&ColumnRef{Column: "*"}}}
	}
|	TOK_IDENT TOK_LPAREN expression_list TOK_RPAREN
	{
		$$ = &FunctionCall{Name: $1, Args: $3}
	}
|	TOK_IDENT TOK_LPAREN TOK_DISTINCT expression_list TOK_RPAREN
	{
		$$ = &FunctionCall{Name: $1, Args: $4, Distinct: true}
	}
|	function_call TOK_OVER window_spec
	{
		fc := $1.(*FunctionCall)
		fc.Over = $3
		$$ = fc
	}

// 窗口规范
window_spec:
	TOK_LPAREN TOK_RPAREN
	{
		$$ = &WindowSpec{}
	}
|	TOK_LPAREN TOK_PARTITION TOK_BY expression_list TOK_RPAREN
	{
		$$ = &WindowSpec{PartitionBy: $4}
	}
|	TOK_LPAREN TOK_ORDER TOK_BY order_by_list TOK_RPAREN
	{
		$$ = &WindowSpec{OrderBy: $4}
	}
|	TOK_LPAREN TOK_PARTITION TOK_BY expression_list TOK_ORDER TOK_BY order_by_list TOK_RPAREN
	{
		$$ = &WindowSpec{PartitionBy: $4, OrderBy: $7}
	}
|	TOK_LPAREN window_frame TOK_RPAREN
	{
		$$ = &WindowSpec{Frame: $2}
	}
|	TOK_LPAREN TOK_PARTITION TOK_BY expression_list window_frame TOK_RPAREN
	{
		$$ = &WindowSpec{PartitionBy: $4, Frame: $5}
	}
|	TOK_LPAREN TOK_ORDER TOK_BY order_by_list window_frame TOK_RPAREN
	{
		$$ = &WindowSpec{OrderBy: $4, Frame: $5}
	}
|	TOK_LPAREN TOK_PARTITION TOK_BY expression_list TOK_ORDER TOK_BY order_by_list window_frame TOK_RPAREN
	{
		$$ = &WindowSpec{PartitionBy: $4, OrderBy: $7, Frame: $8}
	}

// 窗口框架
window_frame:
	TOK_ROWS frame_extent
	{
		$$ = &WindowFrame{Type: RowsFrame, Start: $2}
	}
|	TOK_RANGE frame_extent
	{
		$$ = &WindowFrame{Type: RangeFrame, Start: $2}
	}
|	TOK_ROWS TOK_BETWEEN frame_bound TOK_AND frame_bound
	{
		$$ = &WindowFrame{Type: RowsFrame, Start: $3, End: $5}
	}
|	TOK_RANGE TOK_BETWEEN frame_bound TOK_AND frame_bound
	{
		$$ = &WindowFrame{Type: RangeFrame, Start: $3, End: $5}
	}

// 框架范围
frame_extent:
	frame_bound
	{
		$$ = $1
	}

// 框架边界
frame_bound:
	TOK_UNBOUNDED TOK_PRECEDING
	{
		$$ = &FrameBound{Type: UnboundedPreceding}
	}
|	TOK_UNBOUNDED TOK_FOLLOWING
	{
		$$ = &FrameBound{Type: UnboundedFollowing}
	}
|	TOK_CURRENT TOK_ROW
	{
		$$ = &FrameBound{Type: CurrentRow}
	}
|	expression TOK_PRECEDING
	{
		$$ = &FrameBound{Type: Preceding, Offset: $1}
	}
|	expression TOK_FOLLOWING
	{
		$$ = &FrameBound{Type: Following, Offset: $1}
	}

// 子查询表达式
subquery_expr:
	TOK_LPAREN select_stmt TOK_RPAREN
	{
		$$ = &SubqueryExpr{Select: $2.(*SelectStmt)}
	}

// CASE表达式
case_expr:
	TOK_CASE when_clause_list TOK_END
	{
		$$ = &CaseExpr{WhenList: $2}
	}
|	TOK_CASE when_clause_list TOK_ELSE expression TOK_END
	{
		$$ = &CaseExpr{WhenList: $2, Else: $4}
	}
|	TOK_CASE expression when_clause_list TOK_END
	{
		$$ = &CaseExpr{Expr: $2, WhenList: $3}
	}
|	TOK_CASE expression when_clause_list TOK_ELSE expression TOK_END
	{
		$$ = &CaseExpr{Expr: $2, WhenList: $3, Else: $5}
	}

// WHEN子句列表
when_clause_list:
	when_clause
	{
		$$ = []*WhenClause{$1}
	}
|	when_clause_list when_clause
	{
		$$ = append($1, $2)
	}

// WHEN子句
when_clause:
	TOK_WHEN expression TOK_THEN expression
	{
		$$ = &WhenClause{Condition: $2, Result: $4}
	}

// 字面量
literal:
	TOK_INTEGER
	{
		$$ = &Literal{Value: $1, Type: IntegerLiteral}
	}
|	TOK_FLOAT
	{
		$$ = &Literal{Value: $1, Type: FloatLiteral}
	}
|	TOK_STRING
	{
		$$ = &Literal{Value: $1, Type: StringLiteral}
	}
|	TOK_TRUE
	{
		$$ = &Literal{Value: true, Type: BooleanLiteral}
	}
|	TOK_FALSE
	{
		$$ = &Literal{Value: false, Type: BooleanLiteral}
	}
|	TOK_NULL
	{
		$$ = &Literal{Value: nil, Type: NullLiteral}
	}

// 列引用
column_ref:
	TOK_IDENT
	{
		$$ = &ColumnRef{Column: $1}
	}
|	TOK_IDENT TOK_DOT TOK_IDENT
	{
		$$ = &ColumnRef{Table: $1, Column: $3}
	}

// 比较操作符
comparison_op:
	TOK_EQ { $$ = EQ }
|	TOK_NE { $$ = NE }
|	TOK_LT { $$ = LT }
|	TOK_LE { $$ = LE }
|	TOK_GT { $$ = GT }
|	TOK_GE { $$ = GE }

// 算术操作符
arithmetic_op:
	TOK_PLUS { $$ = PLUS }
|	TOK_MINUS { $$ = MINUS }
|	TOK_MULTIPLY { $$ = MULTIPLY }
|	TOK_DIVIDE { $$ = DIVIDE }
|	TOK_MODULO { $$ = MODULO }
|	TOK_CONCAT { $$ = CONCAT }

// 逻辑操作符
logical_op:
	TOK_AND { $$ = AND }
|	TOK_OR { $$ = OR }

// 一元操作符
unary_op:
	TOK_NOT { $$ = NOT }
|	TOK_MINUS { $$ = MINUS_UNARY }
|	TOK_PLUS { $$ = PLUS_UNARY }

// UPDATE列表
update_list:
	update_item
	{
		$$ = []UpdateExpr{*$1}
	}
|	update_list TOK_COMMA update_item
	{
		$$ = append($1, *$3)
	}

// UPDATE项
update_item:
	TOK_IDENT TOK_EQ expression
	{
		$$ = &UpdateExpr{Column: $1, Value: $3}
	}

// 插入列列表
insert_column_list:
	TOK_IDENT
	{
		$$ = []string{$1}
	}
|	insert_column_list TOK_COMMA TOK_IDENT
	{
		$$ = append($1, $3)
	}

// 列定义列表
column_def_list:
	column_def
	{
		$$ = []*ColumnDef{$1}
	}
|	column_def_list TOK_COMMA column_def
	{
		$$ = append($1, $3)
	}

// 列定义
column_def:
	TOK_IDENT data_type
	{
		$$ = &ColumnDef{
			Name: $1,
			Type: $2,
		}
	}
|	TOK_IDENT data_type TOK_NOT TOK_NULL
	{
		$$ = &ColumnDef{
			Name: $1,
			Type: $2,
			Constraints: []*ColumnConstraint{{
				Type: NotNullConstraint,
			}},
		}
	}
|	TOK_IDENT data_type TOK_PRIMARY TOK_KEY
	{
		$$ = &ColumnDef{
			Name: $1,
			Type: $2,
			Constraints: []*ColumnConstraint{{
				Type: PrimaryKeyConstraint,
			}},
		}
	}

// 数据类型
data_type:
	TOK_INTEGER { $$ = &TypeName{Name: "INTEGER"} }
|	TOK_VARCHAR { $$ = &TypeName{Name: "VARCHAR"} }
|	TOK_DECIMAL { $$ = &TypeName{Name: "DECIMAL"} }
|	TOK_BOOLEAN { $$ = &TypeName{Name: "BOOLEAN"} }
|	TOK_TEXT { $$ = &TypeName{Name: "TEXT"} }
|	TOK_TIMESTAMP { $$ = &TypeName{Name: "TIMESTAMP"} }
|	TOK_DATE { $$ = &TypeName{Name: "DATE"} }
|	TOK_TIME { $$ = &TypeName{Name: "TIME"} }

// VALUES列表
values_list:
	TOK_LPAREN expression_list TOK_RPAREN
	{
		$$ = [][]Expression{$2}
	}
|	values_list TOK_COMMA TOK_LPAREN expression_list TOK_RPAREN
	{
		$$ = append($1, $4)
	}

%%

// 辅助函数
func getFirstExpr(exprs []Expression) Expression {
	if len(exprs) > 0 {
		return exprs[0]
	}
	return nil
}



// Lex 实现yyLexer接口